package cn.edu.thu.tsqualitylite.controller.util;

import cn.edu.thu.tsquality.core.common.datasource.CsvDataSource;
import cn.edu.thu.tsquality.core.common.datasource.IDataSource;
import cn.edu.thu.tsqualitylite.common.constant.Constants;
import cn.edu.thu.tsqualitylite.common.util.DataUtil;
import cn.edu.thu.tsqualitylite.common.util.ServerTable;
import cn.edu.thu.tsqualitylite.record.TabularData;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by stoke on 2018/3/30.
 * E-mail address is zaqthss2009@gmail.com
 * Copyright © stoke. All Rights Reserved.
 *
 * @author stoke
 */
@Controller
public class FileController {

  //  TODO update value
  @RequestMapping(value = "/api/chooseFile", method = RequestMethod.POST)
  @ResponseBody
  @CrossOrigin
  public Map<String, String> chooseFile(@RequestParam("file") MultipartFile file) {
    Map<String, String> fileMap = new HashMap<String, String>();
    String fileName = file.getOriginalFilename();
    fileMap.put("fileName", fileName);
    if (file.isEmpty()) {
      return fileMap;
    }
    String path = Constants.DATA_PATH;
    File dest = new File(path + "/" + fileName);
    if (!dest.getParentFile().exists()) { //判断文件父目录是否存在
      dest.getParentFile().mkdirs();
    }
    try {
      file.transferTo(dest); //保存文件
    } catch (IllegalStateException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    }
    return fileMap;
  }

//  // TODO Download file
//  @RequestMapping(value = "/api/downloadFile", method = RequestMethod.POST)
//  @ResponseBody
//  public String downloadFile(@RequestParam("fileName") String fileName) {
//    // hello
//
//    return null;
//  }

  @RequestMapping(value = "/api/downloadFile", method = RequestMethod.GET)
  @CrossOrigin
  public void downloadFile(
      @RequestParam String type,
      @RequestParam String fileName,
      HttpServletRequest request, HttpServletResponse response) {

    String folder;
    switch (type.toUpperCase()) {
      case "DATA":
        folder = Constants.DATA_PATH;
        break;
      case "RULE":
        folder = Constants.RULE_PATH;
        break;
      case "ERROR":
        folder = Constants.ERROR_PATH;
        break;
      case "REPAIR":
        folder = Constants.REPAIR_PATH;
        break;
      default:
        folder = Constants.DATA_PATH;
        break;
    }
    String csvPath = folder + fileName;

    response.setCharacterEncoding(request.getCharacterEncoding());
    response.setContentType("application/octet-stream");
    FileInputStream fis = null;
    try {
      File file = new File(csvPath);
      fis = new FileInputStream(file);
      response.setHeader("Content-Disposition", "attachment; filename=" + file.getName());
      IOUtils.copy(fis, response.getOutputStream());
      response.flushBuffer();
    } catch (FileNotFoundException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    } finally {
      if (fis != null) {
        try {
          fis.close();
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
    }
  }

  //  TODO update value and method(GET or POST)
  @RequestMapping(value = "/api/viewTable", method = RequestMethod.GET)
  @ResponseBody
  @CrossOrigin
  public TabularData showData(
      @RequestParam String type,
      @RequestParam String csvName) {
    String folder;
    switch (type.toUpperCase()) {
      case "DATA":
        folder = Constants.DATA_PATH;
        break;
      case "RULE":
        folder = Constants.RULE_PATH;
        break;
      case "ERROR":
        folder = Constants.ERROR_PATH;
        break;
      case "REPAIR":
        folder = Constants.REPAIR_PATH;
        break;
      default:
        folder = Constants.DATA_PATH;
        break;
    }
    String csvPath = folder + csvName;
    TabularData csvData = DataUtil.readCSV(csvPath);
    csvData.setFileName(csvName);
    return csvData;
  }

  /**
   * @param filename
   * @return TODO: filter by type if not a absolute path
   */
  @RequestMapping(value = "/api/data/csv", method = RequestMethod.GET)
  @ResponseBody
  public ServerTable viewCsvData(@RequestParam String filename) {
    try {
      if (!filename.startsWith("/")) {
        filename = Constants.DATA_PATH + filename;
      }
      IDataSource csvSource = new CsvDataSource(filename);
      return new ServerTable(csvSource.read());
    } catch (IOException | IllegalStateException e) {
      return null;
    }
  }
}
